package com.cyt.chattlibrary.message;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.launcher.ARouter;
import com.cyt.chattlibrary.message.util.BitmapUtil;
import com.cyt.chattlibrary.message.util.FileUtils;
import com.homegoods.aroutercomment.UserService;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * @author QiQi
 * @ClassName: ImageMessageHandler
 * @date 2018/10/22
 * @description
 */
public class ImageMessageHandler extends MessageHandler<ImageMessage> {
    private static final String TAG = "ImageMessageHandler";
    private static final int COMPRESSED_SIZE = 960;
    private static final int COMPRESSED_QUALITY = 85;
    private static final int THUMB_COMPRESSED_SIZE = 240;
    private static final int THUMB_COMPRESSED_MIN_SIZE = 100;
    private static final int THUMB_COMPRESSED_QUALITY = 30;
    private static final String IMAGE_LOCAL_PATH = "/image/local/";
    private static final String IMAGE_THUMBNAIL_PATH = "/image/thumbnail/";
    @Autowired
    UserService userService;

    public ImageMessageHandler(Context context) {
        super(context);
        ARouter.getInstance().inject(this);
    }

    @Override
    public void decodeMessage(Message msg, ImageMessage content) {
        Uri uri = obtainImageUri(getContext());
        String name = msg.getMessageId() + ".jpg";
        if (msg.getMessageId() == 0) {
            name = msg.getSendTime() + ".jpg";
        }

        String thumb = uri.toString() + IMAGE_THUMBNAIL_PATH;
        String local = uri.toString() + IMAGE_LOCAL_PATH;
        File localFile = new File(local + name);
        if (localFile.exists()) {
            content.setLocalUri(Uri.parse("file//" + local + name));
        }
        File thumbFile = new File(thumb + name);
        if (!TextUtils.isEmpty(content.getBase64()) && !thumbFile.exists()) {
            byte[] data = null;
            data = Base64.decode(content.getBase64(), 2);
            if (!isImageFile(data)) {
                return;
            }

            FileUtils.byte2File(data, thumb, name);
        }
        content.setThumUri(Uri.parse("file://" + thumb + name));
        content.setBase64(null);
    }

    @Override
    public void encodeMessage(Message msg) {
        ImageMessage model = (ImageMessage) msg.getContent();
        Uri uri = obtainImageUri(getContext());
        String name = msg.getMessageId() + ".jpg";
        Options options = new Options();
        options.inJustDecodeBounds = true;

        if (model.getThumUri() != null && model.getThumUri().getScheme() != null && model.getThumUri().getScheme().equals("file")) {
            File file = new File(uri.toString() + IMAGE_THUMBNAIL_PATH + name);
            byte[] data;
            if (file.exists()) {
                model.setThumUri(Uri.parse("file://" + uri.toString() + IMAGE_THUMBNAIL_PATH + name));
                data = FileUtils.file2byte(file);
                if (data != null) {
                    model.setBase64(Base64.encodeToString(data, 2));
                }
            } else {
                try {
                    String thumbPath = model.getThumUri().toString().substring(5);
                    Log.d(TAG, "beforeEncodeMessage Thumbnail not save yet!" + thumbPath);
                    BitmapFactory.decodeFile(thumbPath, options);
                    if (options.outWidth <= THUMB_COMPRESSED_SIZE && options.outHeight < THUMB_COMPRESSED_SIZE) {
                        File src = new File(thumbPath);
                        data = FileUtils.file2byte(src);
                        if (data != null) {
                            model.setBase64(Base64.encodeToString(data, 2));
                            String path = uri.toString() + IMAGE_THUMBNAIL_PATH;
                            if (FileUtils.copyFile(src, path, name) != null) {
                                model.setThumUri(Uri.parse("file://" + path + name));
                            }
                        }
                    } else {
                        Bitmap bitmap = BitmapUtil.getThumbBitmap(getContext(), model.getThumUri(), THUMB_COMPRESSED_SIZE, THUMB_COMPRESSED_MIN_SIZE);
                        if (bitmap != null) {
                            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                            bitmap.compress(Bitmap.CompressFormat.JPEG, THUMB_COMPRESSED_QUALITY, outputStream);
                            data = outputStream.toByteArray();
                            model.setBase64(Base64.encodeToString(data, 2));
                            outputStream.close();
                            FileUtils.byte2File(data, uri.toString() + IMAGE_THUMBNAIL_PATH, name);
                            model.setThumUri(Uri.parse("file://" + uri.toString() + IMAGE_THUMBNAIL_PATH + name));
                            if (!bitmap.isRecycled()) {
                                bitmap.recycle();
                            }
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        if (model.getLocalUri() != null && model.getLocalUri().getScheme() != null && model.getLocalUri().getScheme().equals("file")) {
            File file = new File(uri.toString() + IMAGE_LOCAL_PATH + name);
            if (file.exists()) {
                model.setLocalUri(Uri.parse("file://" + uri.toString() + IMAGE_LOCAL_PATH + name));
            } else {
                try {
                    String localPath = model.getLocalUri().toString().substring(5);
                    BitmapFactory.decodeFile(localPath, options);
                    if (options.outWidth > COMPRESSED_SIZE || options.outHeight > COMPRESSED_SIZE && !model.isIsFull()) {
                        Bitmap bitmap = BitmapUtil.getResizedBitmap(getContext(), model.getLocalUri(), COMPRESSED_SIZE, COMPRESSED_SIZE);
                        if (bitmap != null) {
                            String dir = uri.toString() + IMAGE_LOCAL_PATH;
                            file = new File(dir);
                            if (!file.exists()) {
                                file.mkdirs();
                            }

                            file = new File(dir + name);
                            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
                            bitmap.compress(Bitmap.CompressFormat.JPEG, COMPRESSED_QUALITY, bos);
                            bos.close();
                            model.setLocalUri(Uri.parse("file://" + dir + name));
                            if (!bitmap.isRecycled()) {
                                bitmap.recycle();
                            }
                        }
                    } else if (FileUtils.copyFile(new File(localPath), uri.toString() + IMAGE_LOCAL_PATH, name) != null) {
                        model.setLocalUri(Uri.parse("file://" + uri.toString() + IMAGE_LOCAL_PATH + name));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
    }

    private Uri obtainImageUri(Context context) {
        File file = context.getFilesDir();
        String path = file.getAbsolutePath();
        String userId = userService.getUserId();
        return Uri.parse(path + File.separator + userId);
    }

    private static boolean isImageFile(byte[] data) {
        if (data != null && data.length != 0) {
            Options options = new Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeByteArray(data, 0, data.length, options);
            return options.outWidth != -1;
        } else {
            return false;
        }
    }
}
